# -- coding: utf-8 --
import sys
import io

# 设置标准输出的编码为UTF-8
if sys.stdout.encoding != "UTF-8":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 加载环境变量
load_dotenv()

# 初始化模型
model = ChatOpenAI(
    model="deepseek-chat",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    base_url="https://api.deepseek.com/v1",
    temperature=0.7,
)


def basic_lcel_chain():
    """基础LCEL链演示"""
    print("🔄 基础LCEL链演示")
    print("-" * 40)
    # 创建链：提示词 -> 模型 -> 输出解析器
    promt = ChatPromptTemplate.from_template("用{style}风格解释：{concept}")

    chain = promt | model | StrOutputParser()

    # 执行链
    result = chain.invoke({"style": "幽默有趣", "concept": "机器学习"})

    print("LCEL链执行结果:")
    print(result)

    return chain


def multi_step_chain():
    """多步骤LCEL链"""
    print("\n🔄 多步骤LCEL链演示")
    print("-" * 40)

    # 方法1：使用 RunnablePassthrough（推荐）
    from langchain_core.runnables import RunnablePassthrough

    # 第一步：分析问题
    analysis_prompt = ChatPromptTemplate.from_template(
        "分析这个问题的关键点：{question}"
    )

    # 第二步：生成答案
    answer_prompt = ChatPromptTemplate.from_template(
        """基于以下分析：{analysis}
        
        请回答这个问题：{question}"""
    )

    # 创建分析链
    analysis_chain = analysis_prompt | model | StrOutputParser()

    # 创建完整链
    # 方法1：使用 RunnablePassthrough（更稳定）
    full_chain = (
        {
            "analysis": analysis_chain,
            "question": RunnablePassthrough(),  # 直接传递question
        }
        | answer_prompt
        | model
        | StrOutputParser()
    )

    # 测试复杂问题
    question = "如何从零开始学习人工智能？"
    print(f"❓ 问题: {question}")
    result = full_chain.invoke({"question": question})
    print(f"💡 回答: {result}")

    return full_chain


def alternative_multi_step_chain():
    """替代的多步骤链实现"""
    print("\n🔄 替代的多步骤链实现")
    print("-" * 40)

    # 方法2：分步执行，避免复杂链
    analysis_prompt = ChatPromptTemplate.from_template(
        "分析这个问题的关键点：{question}"
    )

    answer_prompt = ChatPromptTemplate.from_template(
        """基于一下分析{analysis}
        
        请回答这个问题：{question} """
    )

    # 分布执行
    question = "如何从零开始学习人工智能？"
    print(f"❓ 问题: {question}")
    # 第一步：分析
    analysis_messages = analysis_prompt.format_messages(question=question)
    analysis_result = model.invoke(analysis_messages)
    analysis_text = analysis_result.content
    print(f"🔍 分析结果: {analysis_text}")

    # 第二步：生成答案
    answer_messages = answer_prompt.format_messages(
        analysis=analysis_text, question=question
    )
    answer_result = model.invoke(answer_messages)
    print(f"💡 最终回答: {answer_result.content}")


def simple_multi_step_chain():
    """简化的多步骤链"""
    print("\n🔄 简化的多步骤链")
    print("-" * 40)

    # 使用更简单的方法构建多步骤链
    def create_analysis_and_answer(question):
        # 分析步骤
        analysis_prompt = ChatPromptTemplate.from_template(
            "用一句话分析这个问题：{question}"
        )
        analysis_chain = analysis_prompt | model | StrOutputParser()
        analysis = analysis_chain.invoke({"question": question})

        # 回答问题
        answer_prompt = ChatPromptTemplate.from_template(
            "基于分析：'{analysis}'，请回答：{question}"
        )
        answer_prompt = answer_prompt | model | StrOutputParser()
        answer = analysis_chain.invoke({"analysis": analysis, "question": question})
        return analysis, answer

    question = "如何从零开始学习人工智能？"
    print(f"❓ 问题: {question}")

    analysis, answer = create_analysis_and_answer(question)
    print(f"🔍 分析: {analysis}")
    print(f"💡 回答: {answer}")


if __name__ == "__main__":
    print("🎯 Day 3 - LCEL链式表达式学习")
    print("=" * 50)

    basic_lcel_chain()
    multi_step_chain()
    alternative_multi_step_chain()  # 替代实现
    simple_multi_step_chain()  # 简化版本

    print("\n🎉 LCEL链式表达式学习完成！")
